{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 实战分类，实现早停，模型保存，模型加载",
   "id": "8b604d976c489663"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "在分类的过程中加入：\n",
    "1、训练的可视化过程：tensorboard：\n",
    "2、训练中保存最好的模型：SaveCheckPointCallback：\n",
    "3、早停：EarlyStoppingCallback："
   ],
   "id": "7cdbbecfda6ffb6c"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "导入包",
   "id": "e1fb7731ce759bc9"
  },
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-03-06T12:19:43.792571Z",
     "start_time": "2025-03-06T12:19:43.790090Z"
    }
   },
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import tqdm.auto as tqdm\n",
    "import sklearn\n",
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n"
   ],
   "outputs": [],
   "execution_count": 61
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "显示系统硬件信息",
   "id": "77a64d0d2beea6bc"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T12:19:43.846946Z",
     "start_time": "2025-03-06T12:19:43.844088Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(sys.version_info)\n",
    "for moudle in np, pd, sklearn, mpl, torch:\n",
    "    print(moudle.__name__, moudle.__version__)\n",
    "device = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n",
    "print(device)\n",
    "\n"
   ],
   "id": "c27b1bb262552afb",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sys.version_info(major=3, minor=12, micro=3, releaselevel='final', serial=0)\n",
      "numpy 2.0.0\n",
      "pandas 2.2.2\n",
      "sklearn 1.6.1\n",
      "matplotlib 3.9.1\n",
      "torch 2.6.0+cu126\n",
      "cuda:0\n"
     ]
    }
   ],
   "execution_count": 62
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 数据准备和数据预处理",
   "id": "1d0729a78239d782"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T12:19:43.877163Z",
     "start_time": "2025-03-06T12:19:43.846946Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from torchvision import datasets  # 加载数据集\n",
    "from torchvision import transforms  # 将图片转换为tensor\n",
    "\n",
    "# 定义数据集的变换\n",
    "transform = transforms.Compose([\n",
    "    transforms.ToTensor(),  # 将图片转换为tensor\n",
    "    # transforms.Normalize((0.1307,), (0.3081,))  # 归一化\n",
    "])\n",
    "\n",
    "# fashion MNIST 数据集\n",
    "train_ds = datasets.FashionMNIST(\n",
    "    root=\"data\",\n",
    "    train=True,\n",
    "    download=True,\n",
    "    transform=transform\n",
    ")\n",
    "\n",
    "test_ds = datasets.FashionMNIST(\n",
    "    root=\"data\",\n",
    "    train=False,\n",
    "    download=True,\n",
    "    transform=transform\n",
    ")\n",
    "# torchvision 数据集里没有提供训练集和验证集的划分"
   ],
   "id": "bc548b83a1666186",
   "outputs": [],
   "execution_count": 63
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T12:19:43.880258Z",
     "start_time": "2025-03-06T12:19:43.877163Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 打印数据集信息\n",
    "print(train_ds)\n",
    "# 打印测试集的信息\n",
    "print('-' * 50)\n",
    "print(test_ds)"
   ],
   "id": "e9e27ae4882e1ecf",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dataset FashionMNIST\n",
      "    Number of datapoints: 60000\n",
      "    Root location: data\n",
      "    Split: Train\n",
      "    StandardTransform\n",
      "Transform: Compose(\n",
      "               ToTensor()\n",
      "           )\n",
      "--------------------------------------------------\n",
      "Dataset FashionMNIST\n",
      "    Number of datapoints: 10000\n",
      "    Root location: data\n",
      "    Split: Test\n",
      "    StandardTransform\n",
      "Transform: Compose(\n",
      "               ToTensor()\n",
      "           )\n"
     ]
    }
   ],
   "execution_count": 64
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T12:19:43.892172Z",
     "start_time": "2025-03-06T12:19:43.881261Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 将数据转存到DataLoaders中,只有训练集需要shuffle。\n",
    "train_loader = torch.utils.data.DataLoader(train_ds, batch_size=32, shuffle=True)\n",
    "# 把测试数据也转存到DataLoaders中，变成一个batch\n",
    "val_loader = torch.utils.data.DataLoader(test_ds, batch_size=32, shuffle=False)\n",
    "# 打印DataLoaders的类型\n",
    "print(type(train_loader))\n",
    "# 查看在dataloader中取出的batch的大小\n",
    "print('-' * 50)\n",
    "for data in train_loader:\n",
    "    print(type(data))\n",
    "    print(type(data[0]))\n",
    "    print(data[0].shape)\n",
    "    print(type(data[1]))\n",
    "    print(data[1].shape)\n",
    "    break\n",
    "print('-' * 50)\n",
    "for data, label in train_loader:\n",
    "    print(data.shape)\n",
    "    print(label.shape)\n",
    "    break"
   ],
   "id": "63e13cc86c06aa2b",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'torch.utils.data.dataloader.DataLoader'>\n",
      "--------------------------------------------------\n",
      "<class 'list'>\n",
      "<class 'torch.Tensor'>\n",
      "torch.Size([32, 1, 28, 28])\n",
      "<class 'torch.Tensor'>\n",
      "torch.Size([32])\n",
      "--------------------------------------------------\n",
      "torch.Size([32, 1, 28, 28])\n",
      "torch.Size([32])\n"
     ]
    }
   ],
   "execution_count": 65
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 定义模型",
   "id": "8a0b18720a668025"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T12:19:43.896531Z",
     "start_time": "2025-03-06T12:19:43.892172Z"
    }
   },
   "cell_type": "code",
   "source": [
    "class NeuralNetwork(nn.Module):\n",
    "    def __init__(self):\n",
    "        # 调用父类的初始化方法\n",
    "        super().__init__()\n",
    "        # 定义网络结构\n",
    "        self.flatten = nn.Flatten()\n",
    "        self.linear_relu_stack = nn.Sequential(\n",
    "            nn.Linear(28 * 28, 300),  # 输入层到隐藏层\n",
    "            nn.ReLU(),  # 激活函数\n",
    "            nn.Linear(300, 100),  # 隐藏层到输出层\n",
    "            nn.ReLU(),  # 激活函数\n",
    "            nn.Linear(100, 10),  # 输出层\n",
    "        )\n",
    "\n",
    "    # 定义前向传播过程\n",
    "    def forward(self, x):\n",
    "        # 定义前向传播过程\n",
    "        x = self.flatten(x)\n",
    "        logits = self.linear_relu_stack(x)\n",
    "        return logits\n",
    "\n",
    "\n",
    "model = NeuralNetwork()"
   ],
   "id": "e2fe008fbcdc2845",
   "outputs": [],
   "execution_count": 66
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 训练",
   "id": "69aabc7ac2b6d191"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "pytorch的训练需要自行实现：\n",
    "1. 定义损失函数\n",
    "2. 定义优化器\n",
    "3. 定义tensorboard\n",
    "4. 定义earlystopping\n",
    "5. 定义checkpoint\n",
    "6. 定义训练循环，步数\n",
    "7. 训练"
   ],
   "id": "10d8462e182f83fe"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "",
   "id": "81ca2908b617936a"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "定义损失器和优化器",
   "id": "8295992c187a91f8"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T12:19:43.902007Z",
     "start_time": "2025-03-06T12:19:43.896531Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "# 定义损失函数,nn.CrossEntropyLoss()是多分类用的损失函数,叫做交叉熵\n",
    "loss_func = nn.CrossEntropyLoss()\n",
    "# 定义优化器,SGD是随机梯度下降法,momentum是动量法,lr是学习率\n",
    "optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)"
   ],
   "id": "c36f4bd131ac7a52",
   "outputs": [],
   "execution_count": 67
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "定义tensorboard",
   "id": "dd443eaca49a6b86"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T12:19:43.908698Z",
     "start_time": "2025-03-06T12:19:43.902007Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from torch.utils.tensorboard import SummaryWriter\n",
    "\n",
    "\n",
    "class TensorBoardCallback:\n",
    "    def __init__(self, log_dir, flush_secs=10):\n",
    "        \"\"\"\n",
    "        Args:\n",
    "            log_dir (str): dir to write log.\n",
    "            flush_secs (int, optional): write to dsk each flush_secs seconds. Defaults to 10.\n",
    "        \"\"\"\n",
    "        self.writer = SummaryWriter(log_dir=log_dir,\n",
    "                                    flush_secs=flush_secs)  # 实例化SummaryWriter, log_dir是log存放路径，flush_secs是每隔多少秒写入磁盘\n",
    "\n",
    "    def draw_model(self, model, input_shape):  #graphs\n",
    "        self.writer.add_graph(model, input_to_model=torch.randn(input_shape))  # 画模型图\n",
    "\n",
    "    def add_loss_scalars(self, step, loss, val_loss):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/loss\",\n",
    "            tag_scalar_dict={\"loss\": loss, \"val_loss\": val_loss},\n",
    "            global_step=step,\n",
    "        )  # 画loss曲线, main_tag是主tag，tag_scalar_dict是子tag，global_step是步数\n",
    "\n",
    "    def add_acc_scalars(self, step, acc, val_acc):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/accuracy\",\n",
    "            tag_scalar_dict={\"accuracy\": acc, \"val_accuracy\": val_acc},\n",
    "            global_step=step,\n",
    "        )  # 画acc曲线, main_tag是主tag，tag_scalar_dict是子tag，global_step是步数\n",
    "\n",
    "    def add_lr_scalars(self, step, learning_rate):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/learning_rate\",\n",
    "            tag_scalar_dict={\"learning_rate\": learning_rate},\n",
    "            global_step=step,\n",
    "        )  # 画lr曲线, main_tag是主tag，tag_scalar_dict是子tag，global_step是步数\n",
    "\n",
    "    def __call__(self, step, **kwargs):\n",
    "        # add loss,把loss，val_loss取掉，画loss曲线\n",
    "        loss = kwargs.pop(\"loss\", None)\n",
    "        val_loss = kwargs.pop(\"val_loss\", None)\n",
    "        if loss is not None and val_loss is not None:\n",
    "            self.add_loss_scalars(step, loss, val_loss)  # 画loss曲线\n",
    "        # add acc\n",
    "        acc = kwargs.pop(\"acc\", None)\n",
    "        val_acc = kwargs.pop(\"val_acc\", None)\n",
    "        if acc is not None and val_acc is not None:\n",
    "            self.add_acc_scalars(step, acc, val_acc)  # 画acc曲线\n",
    "        # add lr\n",
    "        learning_rate = kwargs.pop(\"lr\", None)\n",
    "        if learning_rate is not None:\n",
    "            self.add_lr_scalars(step, learning_rate)  # 画lr曲线"
   ],
   "id": "b6c8625eb314006c",
   "outputs": [],
   "execution_count": 68
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "定义checkpoint",
   "id": "23537d6af54ea748"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T12:19:43.916441Z",
     "start_time": "2025-03-06T12:19:43.908698Z"
    }
   },
   "cell_type": "code",
   "source": [
    "class SaveCheckpointCallback:\n",
    "    def __init__(self, save_path, save_freq=500, save_best_only=True):\n",
    "        \"\"\"\n",
    "        保存模型检查点的回调类。\n",
    "        参数：\n",
    "            save_path (str): 保存检查点的目录路径。\n",
    "            save_freq (int, 可选): 保存检查点的频率。默认为10。\n",
    "            save_best_only (bool, 可选): 如果为True，仅保存最佳模型；否则，每个epoch都保存。默认为True。\n",
    "        \"\"\"\n",
    "        self.save_path = save_path  # 保存检查点的目录路径\n",
    "        self.save_freq = save_freq  # 保存检查点的频率\n",
    "        self.save_best_only = save_best_only  # 是否仅保存最佳模型\n",
    "        self.best_metric = -1  # 初始化最佳指标为-1\n",
    "\n",
    "        # mkdir，如果不存在就创建文件夹\n",
    "        if not os.path.exists(self.save_path):\n",
    "            os.mkdir(self.save_path)\n",
    "\n",
    "    # __call__方法是回调函数的入口，会在训练过程中调用\n",
    "    def __call__(self, step, stat_dict, metric=None):\n",
    "        \"\"\"\n",
    "        回调函数，在训练过程中被调用。\n",
    "        \n",
    "        参数：\n",
    "            step (int): 当前的训练步数或epoch数。\n",
    "            stat_dict (dict): 模型的状态字典，通常包含模型的参数。\n",
    "            metric (float, 可选): 当前的评估指标，用于判断是否保存最佳模型。默认为None。\n",
    "        \"\"\"\n",
    "        if step % self.save_freq > 0:\n",
    "            return\n",
    "\n",
    "        # 如果指标更好，保存最好的模型\n",
    "        if self.save_best_only:  # 如果只保存最佳模型\n",
    "            assert metric is not None, \"metric should not be None when save_best_only is True\"  # 断言metric不为空\n",
    "            # 如果当前指标大于或等于最佳指标\n",
    "            if metric >= self.best_metric:\n",
    "                # 保存最好的模型，覆盖原有模型，不保存step，只保存state_dict，及模型的参数，不保存优化器参数\n",
    "                torch.save(stat_dict, os.path.join(self.save_path, \"best.ckpt\"))\n",
    "                # 更新最佳指标\n",
    "                self.best_metric = metric\n",
    "        else:\n",
    "            # 如果不是仅保存最佳模型，则按照步数保存模型\n",
    "            # 保存模型检查点，文件名为\"{step}.ckpt\"\n",
    "            torch.save(stat_dict, os.path.join(self.save_path, \"f{step}.ckpt\"))"
   ],
   "id": "dc7c0ca5ac9e6c16",
   "outputs": [],
   "execution_count": 69
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "定义earlystopping",
   "id": "e511523b823e7b84"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T12:19:43.922284Z",
     "start_time": "2025-03-06T12:19:43.917444Z"
    }
   },
   "cell_type": "code",
   "source": [
    "class EarlyStoppingCallback:\n",
    "    # c\n",
    "    def __init__(self, patience=5, min_delta=0.01):\n",
    "        \"\"\"\n",
    "        早停（Early Stopping）回调类，用于在训练过程中监控模型性能，防止过拟合。\n",
    "        当验证集上的性能在连续 `patience` 个 epoch 内没有改善时，停止训练。\n",
    "        Args:\n",
    "            patience (int, optional): \n",
    "                在训练停止前，可以容忍验证集性能没有改善的最大 epoch 数。\n",
    "                例如，如果 `patience=5`，则在验证集性能连续 5 个 epoch 没有改善时，训练将停止。\n",
    "                默认值为 5。\n",
    "                \n",
    "            min_delta (float, optional): \n",
    "                监控指标的最小变化量，用于判断是否算作性能改善。\n",
    "                如果验证集性能的变化量小于 `min_delta`，则认为性能没有改善。\n",
    "                例如，如果 `min_delta=0.01`，则验证集性能的变化必须大于 0.01 才算作改善。\n",
    "                默认值为 0.01。\n",
    "        \"\"\"\n",
    "        self.patience = patience  # 容忍度\n",
    "        self.min_delta = min_delta  # 最小变化\n",
    "        self.best_metric = -1  # 初始化最佳指标为-1\n",
    "        self.counter = 0  # 计数器，记录连续多少个epoch没有提升\n",
    "\n",
    "    # 定义__call__方法，在训练过程中调用.回调函数的入口，会在训练过程中调用\n",
    "    def __call__(self, metric):\n",
    "        \"\"\"\n",
    "        回调函数，在每个 epoch 结束后调用，检查是否需要停止训练。\n",
    "        Args:\n",
    "            current_metric (float): 当前 epoch 的验证集性能指标。\n",
    "        Returns:\n",
    "            bool: 如果需要停止训练，返回 True；否则返回 False。\n",
    "        \"\"\"\n",
    "        if metric >= self.best_metric + self.min_delta:  # 如果当前指标大于或等于最佳指标+最小变化\n",
    "            self.best_metric = metric  # 更新最佳指标\n",
    "            self.counter = 0  # 计数器清零\n",
    "        else:\n",
    "            self.counter += 1  # 计数器加1\n",
    "\n",
    "    @property  # 定义@property装饰器，使得实例可以像属性一样访问patience和min_delta\n",
    "    def early_stop(self):\n",
    "        return self.counter >= self.patience  # 如果计数器大于或等于容忍度，则返回True，表示停止训练"
   ],
   "id": "e16481875dc7ce98",
   "outputs": [],
   "execution_count": 70
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 定义评估函数",
   "id": "27936760d129090f"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T12:19:43.928154Z",
     "start_time": "2025-03-06T12:19:43.922284Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "\n",
    "@torch.no_grad()  # 装饰器，禁止梯度计算\n",
    "def evaluating(model, dataloader, loss_func):\n",
    "    loss_list = []\n",
    "    pred_list = []\n",
    "    label_list = []\n",
    "    for datas, labels in dataloader:\n",
    "        datas = datas.to(device)\n",
    "        labels = labels.to(device)\n",
    "        # 正向传播\n",
    "        logits = model(datas)\n",
    "\n",
    "        loss = loss_func(logits, labels)\n",
    "        loss_list.append(loss.item())\n",
    "\n",
    "        preds = logits.argmax(axis=-1)\n",
    "\n",
    "        pred_list.extend(preds.cpu().numpy().tolist())\n",
    "        label_list.extend(labels.cpu().numpy().tolist())\n",
    "\n",
    "    acc = accuracy_score(label_list, pred_list)\n",
    "    return np.mean(loss_list), acc"
   ],
   "id": "2688f5a8c646d222",
   "outputs": [],
   "execution_count": 71
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 训练",
   "id": "8f4f67e4574711fb"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T12:19:43.934876Z",
     "start_time": "2025-03-06T12:19:43.928154Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# \n",
    "def training(\n",
    "        model,\n",
    "        train_loader,\n",
    "        val_loader,\n",
    "        epoch,\n",
    "        loss_func,\n",
    "        optimizer,\n",
    "        tensorboard_callback=None,\n",
    "        save_checkpoint_callback=None,\n",
    "        early_stopping_callback=None,\n",
    "        sval_step=500):\n",
    "    \"\"\"\n",
    "    训练函数，用于训练模型并监控验证集性能。\n",
    "    Args:\n",
    "        model: 要训练的模型。\n",
    "        train_loader: 训练数据加载器，提供训练数据和标签。\n",
    "        val_loader: 验证数据加载器，提供验证数据和标签。\n",
    "        epoch: 总的训练轮数。\n",
    "        loss_func: 损失函数，用于计算模型的损失。\n",
    "        optimizer: 优化器，用于更新模型的参数。\n",
    "        tensorboard_callback: TensorBoard 回调函数，用于记录训练过程中的指标。\n",
    "        save_checkpoint_callback: 保存检查点的回调函数，用于保存模型。\n",
    "        early_stopping_callback: 早停回调函数，用于防止过拟合。\n",
    "        sval_step (int, optional): 每隔多少步进行一次验证。默认为500。\n",
    "    \"\"\"\n",
    "    record_dict = {\n",
    "        \"train\": [],  # 记录训练过程中的指标\n",
    "        \"val\": []  # 记录验证过程中的指标\n",
    "    }\n",
    "    # 全局步数\n",
    "    global_step = 0\n",
    "    # 切换到训练模式\n",
    "    model.train()\n",
    "    # 使用 tqdm 显示进度条，总步数为 sval_step\n",
    "    with tqdm.tqdm(total=epoch * len(train_loader)) as pbar:\n",
    "        for epoch_id in range(epoch):\n",
    "            # 遍历训练数据加载器，获取数据和标签\n",
    "            for datas, labels in train_loader:\n",
    "                # 把数据转存到device\n",
    "                datas = datas.to(device)\n",
    "                # 把标签转存到device\n",
    "                labels = labels.to(device)\n",
    "                # # 优化器梯度清零，避免梯度累积\n",
    "                optimizer.zero_grad()\n",
    "                # 模型前向计算，获取输出\n",
    "                logits = model(datas)\n",
    "                # 计算损失\n",
    "                loss = loss_func(logits, labels)\n",
    "                #  损失反向传播，计算梯度\n",
    "                loss.backward()\n",
    "                # # 优化器更新模型参数\n",
    "                optimizer.step()\n",
    "                # 获取预测类别\n",
    "                preds = logits.argmax(axis=-1)  # 预测类别\n",
    "                # 计算准确率\n",
    "                acc = accuracy_score(labels.cpu().numpy(), preds.cpu().numpy())\n",
    "                # 将损失从 GPU 移到 CPU，并转换为 Python 标量\n",
    "                loss = loss.cpu().item()\n",
    "\n",
    "                record_dict[\"train\"].append({\n",
    "                    \"loss\": loss,\n",
    "                    \"acc\": acc,\n",
    "                    \"step\": global_step\n",
    "                })\n",
    "                # 切换回训练模式\n",
    "                model.train()\n",
    "\n",
    "                # evaluating\n",
    "                if global_step % sval_step == 0:\n",
    "                    # 验证模式\n",
    "                    model.eval()\n",
    "                    val_loss, val_acc = evaluating(model, val_loader, loss_func)\n",
    "                    record_dict[\"val\"].append({  # 记录验证过程中的指标\n",
    "                        \"loss\": val_loss,\n",
    "                        \"acc\": val_acc,\n",
    "                        \"step\": global_step\n",
    "                    })\n",
    "                    # 切换回训练模式\n",
    "                    model.train()\n",
    "\n",
    "                    # 1、tensorboard\n",
    "                    if tensorboard_callback is not None:\n",
    "                        tensorboard_callback(global_step,\n",
    "                                             loss=loss, acc=acc,\n",
    "                                             val_loss=val_loss, val_acc=val_acc,\n",
    "                                             lr=optimizer.param_groups[0][\"lr\"])\n",
    "\n",
    "                    # 2、save_checkpoint_callback\n",
    "                    if save_checkpoint_callback is not None:\n",
    "                        save_checkpoint_callback(global_step, model.state_dict(), metric=val_acc)\n",
    "\n",
    "                    # 3、early_stopping_callback\n",
    "                    if early_stopping_callback is not None:\n",
    "                        early_stopping_callback(val_acc)\n",
    "                        if early_stopping_callback.early_stop:\n",
    "                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n",
    "                            return record_dict\n",
    "                # 全局步数加1\n",
    "                global_step += 1\n",
    "                # 进度条更新\n",
    "                pbar.update(1)\n",
    "                # 进度条显示\n",
    "                pbar.set_postfix({\"epoch\": epoch_id})\n",
    "\n",
    "    return record_dict\n"
   ],
   "id": "e07d88153e3ccd3e",
   "outputs": [],
   "execution_count": 72
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T12:21:57.112686Z",
     "start_time": "2025-03-06T12:19:43.934876Z"
    }
   },
   "cell_type": "code",
   "source": [
    "epoch = 100\n",
    "# 1. tensorboard 可视化\n",
    "tensorboard_callback = TensorBoardCallback(\"runs\")\n",
    "tensorboard_callback.draw_model(model, [1, 28, 28])\n",
    "# 2. save best\n",
    "save_ckpt_callback = SaveCheckpointCallback(\"checkpoints\", save_best_only=True)\n",
    "# 3. early stop\n",
    "early_stop_callback = EarlyStoppingCallback(patience=10)\n",
    "# early_stop_callback = None\n",
    "model = model.to(device)\n",
    "# 训练\n",
    "record = training(model,\n",
    "                  train_loader,\n",
    "                  val_loader,\n",
    "                  epoch,\n",
    "                  loss_func,\n",
    "                  optimizer,\n",
    "                  tensorboard_callback,\n",
    "                  save_ckpt_callback,\n",
    "                  early_stop_callback,\n",
    "                  sval_step=1000\n",
    "                  )\n"
   ],
   "id": "cfe4bf7d6a27337f",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "  0%|          | 0/187500 [00:00<?, ?it/s]"
      ],
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "95c9a92369334b8faeb95c2153478837"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Early stop at epoch 13 / global_step 26000\n"
     ]
    }
   ],
   "execution_count": 73
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 画图观察损失和准确率变化",
   "id": "cd3a4e5c521015bb"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T12:21:57.216285Z",
     "start_time": "2025-03-06T12:21:57.112686Z"
    }
   },
   "cell_type": "code",
   "source": [
    "#画线要注意的是损失是不一定在零到1之间的\n",
    "def plot_learning_curves(record_dict, sample_step=500):\n",
    "    # build DataFrame\n",
    "    train_df = pd.DataFrame(record_dict[\"train\"]).set_index(\"step\").iloc[::sample_step]\n",
    "    val_df = pd.DataFrame(record_dict[\"val\"]).set_index(\"step\")\n",
    "    # print(train_df.head())\n",
    "    # print(val_df.head())\n",
    "    # plot\n",
    "    fig_num = len(train_df.columns) #因为有loss和acc两个指标，所以画个子图\n",
    "    fig, axs = plt.subplots(1, fig_num, figsize=(5 * fig_num, 5)) #fig_num个子图，figsize是子图大小\n",
    "    for idx, item in enumerate(train_df.columns):    \n",
    "        #index是步数，item是指标名字\n",
    "        axs[idx].plot(train_df.index, train_df[item], label=f\"train_{item}\")\n",
    "        axs[idx].plot(val_df.index, val_df[item], label=f\"val_{item}\")\n",
    "        axs[idx].grid()\n",
    "        axs[idx].legend()\n",
    "        x_data=range(0, train_df.index[-1], 5000) #每隔5000步标出一个点\n",
    "        axs[idx].set_xticks(x_data)\n",
    "        axs[idx].set_xticklabels(map(lambda x: f\"{int(x/1000)}k\", x_data)) #map生成labal\n",
    "        axs[idx].set_xlabel(\"step\")\n",
    "    \n",
    "    plt.show()\n",
    "\n",
    "plot_learning_curves(record, sample_step=500)  #横坐标是 steps"
   ],
   "id": "28eea541a0f391d4",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 1000x500 with 2 Axes>"
      ],
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAzoAAAHACAYAAABqJx3iAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/TGe4hAAAACXBIWXMAAA9hAAAPYQGoP6dpAADW3klEQVR4nOzdeXyU5bnw8d8ze/Z9YQkECJuAgAoKqHUDlJZWq62n2rq02k16aqmnLee0VutbfV+tiqe19dRW7aLW1lbbU6mCKLKLoCggBELIAmTfJplk9uf945lnMtlnkkkmyVzfzycfyKz3nZlknuu5rvu6FVVVVYQQQgghhBBiHDHEegBCCCGEEEIIEW0S6AghhBBCCCHGHQl0hBBCCCGEEOOOBDpCCCGEEEKIcUcCHSGEEEIIIcS4I4GOEEIIIYQQYtyRQEcIIYQQQggx7kigI4QQQgghhBh3TLEeQDj8fj9nz54lJSUFRVFiPRwhhIgbqqrS2trKxIkTMRjk3JhOPpeEECJ2wv1sGhOBztmzZykoKIj1MIQQIm5VVlYyefLkWA9j1JDPJSGEiL2BPpvGRKCTkpICaJNJTU2N+P4ej4fNmzezatUqzGZztIc3KsXjnCE+5x2PcwaZ90jN2263U1BQEPw7LDTyuTQ4Mu/4mXc8zhnic96xmHO4n01jItDRywJSU1MH/YGSmJhIampqXL3p4m3OEJ/zjsc5g8x7pOct5VldyefS4Mi842fe8ThniM95x3LOA302ScG1EEIIIYQQYtyRQEcIIYQQQggx7kigI4QQQgghhBh3xsQaHSHE6KSqKl6vF5/PN+LP7fF4MJlMOJ3OmDx/rER73kajEZPJJGtwhBBCjDsS6AghBsXtdlNVVUV7e3tMnl9VVfLz86msrIyrg/ThmHdiYiITJkzAYrFE5fGEEEKI0UACHSFExPx+P6dOncJoNDJx4kQsFsuIBxt+v5+2tjaSk5PjaiPLaM5bVVXcbjd1dXWcOnWKmTNnxtXPUgghxPgmgY4QImJutxu/309BQQGJiYkxGYPf78ftdmOz2eLq4Dza805ISMBsNlNeXh58XCGEEGI8iJ+jAyFE1MVTgDGeyesohBBiPJJPNyGEEEIIIcS4I4GOEEIIIYQQYtyRQEcIIQapsLCQjRs3RuWxtm3bhqIoNDc3R+Xx4sn27dtZu3YtEydORFEUXn311QHvs23bNs477zysVitFRUU899xzwz5OIYQQI0sCHSFEXLnsssu4++67o/JY7733Hl/96lej8lhi8BwOBwsXLuTJJ58M6/anTp3ik5/8JJdffjkHDx7k7rvv5o477uCNN94Y5pEKIYQYSdJ1TQghQqiqis/nw2Qa+M9jTk7OCIxIDOSaa67hmmuuCfv2Tz31FNOmTePRRx8FYO7cuezcuZPHH3+c1atXD9cwhRBCjLBxH+gc2fF3bNvuI12ZCGvWxHo4QoxLqqrS4fGN6HP6/X463D5SVDXs+9x222288847vPPOOzzxxBMAPPvss9x+++1s2rSJH/7whxw6dIjNmzdTUFDA+vXr2bt3Lw6Hg7lz5/LQQw9x1VVXBR+vsLCQu+++O5ghUhSFp59+mtdee4033niDSZMm8eijj/LpT396UHP861//yr333ktJSQkTJkzgW9/6Ft/5zneC1//yl7/k8ccfp7KykrS0NC655BJefvllAF5++WXuv/9+SkpKSExMZPHixfz9738nKSlpUGMZT/bs2dPldQRYvXp1v5k+l8uFy+UKfm+32wHweDx4PJ6Ix6DfZzD3Hctk3sMz71cPnuWfh6p59IYFpCWYh+U5IiWvdfzMOxZzDve5xn2g43F1MM9XijvWAxFiHOvw+Djn3tiU/Ry+byXJRmNYt33iiSc4fvw48+fP5yc/+QkAR44cAeAHP/gBP/vZz5g+fToZGRlUVlayZs0afvrTn2K1Wvn973/P2rVrKS4uZsqUKX0+x/3338/DDz/MI488ws9//nNuvvlmysvLyczMjGheBw4c4POf/zz33XcfN954I7t37+ab3/wmGRkZfPazn2X//v38+7//O3/4wx9Yvnw5jY2N7NixA4Cqqiq+8IUv8PDDD3PdddfR2trKjh07UCMICsez6upq8vLyulyWl5eH3W6no6ODhISEHvd56KGHuP/++3tcvnnz5iHtJbVly5ZB33csk3lHj6rCT9830uxW+MXLb7I4a3T9nstrHT9Gcs7t7e1h3W7cBzoGWyoAiXTEeCRCiFhLS0vDYrGQmJhIfn4+AMeOHQPgJz/5CStXrgzeNjMzk4ULFwa/f+CBB3jllVf4xz/+wbp16/p8jttuu40vfOELADz44IP893//N/v27ePqq6+OaKyPPfYYV155JT/60Y8AmDVrFh9//DGP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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 74
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 评估当前保存的模型，和上线模型的效果",
   "id": "5c436d51a7f035d2"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T12:21:57.887252Z",
     "start_time": "2025-03-06T12:21:57.216285Z"
    }
   },
   "cell_type": "code",
   "source": [
    "model.load_state_dict(torch.load(\"checkpoints/best.ckpt\", weights_only=True,map_location=\"cuda:0\"))\n",
    "\n",
    "model.eval()\n",
    "loss, acc = evaluating(model, val_loader, loss_func)\n",
    "print(f\"loss:{loss:.4f}\\naccuracy:{acc:.4f}\")"
   ],
   "id": "681a6edcc4e555d9",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss:0.3901\n",
      "accuracy:0.8625\n"
     ]
    }
   ],
   "execution_count": 75
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
